﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CM.BL.BE;
using SAP.Middleware.Connector;

namespace CM.DL.DALC.SAP
{
    public class SolicitudPedidoDALC
    {
        private string _connId = string.Empty;
        #region Singleton
        public static SolicitudPedidoDALC getInstance(string pConnId)
        {
            if (_instance == null)
            {
                lock (typeof(SolicitudPedidoDALC))
                {
                    if (_instance == null)
                    {
                        _instance = new SolicitudPedidoDALC(pConnId);
                    }
                }
            }
            _instance._connId = pConnId;
            return _instance;
        }
        private SolicitudPedidoDALC(string pConnId) { this._connId = pConnId; }
        private static volatile SolicitudPedidoDALC _instance = null;
        #endregion

        public string releaseSP(string pSP, string pCodLib, string pPosicion, out bool pLiberado)
        {
            string retval = string.Empty; IRfcFunction function = null;
            DestConfig dc = new DestConfig(); pLiberado = false;
            RfcDestination dest = null;
            try
            {
                dest = DALC.getDestination(); //@@@
                function = dest.Repository.CreateFunction("BAPI_REQUISITION_RELEASE");
                function.SetValue("NUMBER", pSP);
                function.SetValue("REL_CODE", pCodLib);
                function.SetValue("ITEM", pPosicion);
                function.SetValue("USE_EXCEPTIONS", string.Empty);
                //function.SetValue("NO_COMMIT_WORK", "X");
                function.Invoke(dest);

                IRfcTable RETURN = function.GetTable("RETURN");
                foreach (IRfcStructure itm in RETURN)
                {
                    retval += itm["MESSAGE"].GetString();
                }

                string strRelSta = function.GetString("REL_STATUS_NEW");
                string strRelInd = function.GetString("REL_INDICATOR_NEW");
                //int retCode = function.GetInt("RET_CODE");

                if (string.IsNullOrEmpty(retval))
                {
                    //se hizo la liberación
                    retval = "Pedido " + pSP + " - Posición " + pPosicion + " liberado.";
                    pLiberado = true;
                }
            }
            catch (RfcCommunicationException e)
            {
                // network problem...
            }
            catch (RfcLogonException e)
            {
                // user could not logon...
            }
            catch (RfcAbapRuntimeException e)
            {
                // serious problem on ABAP system side...
            }
            catch (RfcAbapBaseException e)
            {
                // The function module returned an ABAP exception, an ABAP message
                // or an ABAP class-based exception...
            }
            catch (RfcBaseException e)
            {
                // Grabar Log de errores con e.message
                retval += e.Message;
            }
            finally
            {
                //RfcDestinationManager.UnregisterDestinationConfiguration(dc);
            }
            return retval;
        }

        public string getItemsSPForRelease(out List<SolicitudPedidoBE> lstSP)
        {
            lstSP = new List<SolicitudPedidoBE>(); string retVal = string.Empty; SolicitudPedidoBE objSP = null;
            IRfcFunction function = null;
            //usamos item, contacto y solictante de PO por ser similares
            POItemBE itm; POContactoBE con; POSolicitanteBE sol;
            DestConfig dc = new DestConfig(); DateTime fecha; DateTime fechaON; RfcDestination dest = null;
            try
            {
                dest = DALC.getDestination(); //@@@
                function = dest.Repository.CreateFunction("ZCM_MM_003");
                function.Invoke(dest);

                IRfcTable PO_HEADERS = function.GetTable("PO_HEADERS");
                IRfcTable PO_ITEMS = function.GetTable("PO_ITEMS");
                IRfcTable PO_LINES = function.GetTable("PO_LINES");
                IRfcTable PO_CONTACTS = function.GetTable("PO_CONTACTS");
                IRfcTable PO_REQUESTORS = function.GetTable("PO_REQUESTOR");

                retVal = function.GetString("E_ERROR");
                string aux = string.Empty;

                foreach (IRfcStructure PO_HEADER in PO_HEADERS)
                {
                    objSP = new SolicitudPedidoBE();
                    objSP.PO = PO_HEADER["PO_NUMBER"].GetString();// Nro OC
                    objSP.Sociedad = PO_HEADER["CO_CODE"].GetString();// Sociedad
                    objSP.ClaseDoc = PO_HEADER["DOC_TYPE"].GetString();// Clase de documento de compras
                    objSP.CodUsuario = PO_HEADER["CREATED_BY"].GetString();
                    objSP.OrgCompras = PO_HEADER["PURCH_ORG"].GetString();// Organización de compras
                    objSP.GrpCompras = PO_HEADER["PUR_GROUP"].GetString(); // Grupo de compras
                    objSP.Moneda = PO_HEADER["CURRENCY"].GetString(); // Clave de moneda
                    objSP.TipoCambio = PO_HEADER["EXCH_RATE"].GetDecimal();// Tipo de cambio
                    fecha = Convert.ToDateTime(PO_HEADER["DOC_DATE"].GetString());// Fecha
                    objSP.Fecha = fecha.ToString("dd/MM/yy");// Fecha
                    objSP.ClaseDocT = PO_HEADER["INCOTERMS2"].GetString();
                    objSP.NomSoc = PO_HEADER["BUTXT"].GetString(); //Nombre de la sociedad
                    objSP.NomSolicitante = PO_HEADER["NAME_TEXT"].GetString(); // Nombre SOlicitante
                    fechaON = Convert.ToDateTime(PO_HEADER["CREATED_ON"].GetString());// Fecha
                    objSP.FechaOn = fechaON.ToString("dd/MM/yy");// Fecha
                    objSP.TotBruto = PO_HEADER["TARGET_VAL"].GetDecimal();
                    objSP.TotNeto = PO_HEADER["TARGET_VAL"].GetDecimal();

                    //objSP.CondPago = PO_HEADER["PMNTTRMS"].GetString();// Cond. Pago
                    //objSP.CondPagoT = PO_HEADER["SALES_PERS"].GetString(); 
                    //objSP.CodProveedor = PO_HEADER["VENDOR"].GetString();// Proveedor Cod
                    //objSP.DescProveedor = PO_HEADER["VEND_NAME"].GetString();// Proveedor Desc                    
                    ////REL_GROUP / REL_STRAT / REL_IND
                    //objSP.LibGrp = PO_HEADER["REL_GROUP"].GetString();// Grupo de liberación
                    //objSP.LibEst = PO_HEADER["REL_STRAT"].GetString();// Estrategia de liberación
                    //objSP.LibInd = PO_HEADER["REL_IND"].GetString(); // Estado de liberación
                    ////REL_STATUS
                    //objSP.LibCod = PO_HEADER["REF_1"].GetString(); // Código de liberación (para el usuario)                   
                    ////objPO.NomCrea = PO_HEADER["NAME_TEXT"].GetString(); // Nombre del creador de la OC

                    //objSP.Telefono = PO_HEADER["TELEPHONE"].GetString();//teléfono del proveedor                    
                    ////objPO.DesUsuario = PO_HEADER["SALES_PERS"].GetString();

                    aux = string.Empty;
                    foreach (IRfcStructure PO_LINE in PO_LINES)
                    {
                        if (PO_LINE["PO_NUMBER"].GetString().Equals(objSP.PO))
                        {
                            aux += PO_LINE["TDLINE"].GetString();
                            if (PO_LINE["TDFORMAT"].GetString().Equals("*"))
                            {
                                aux += "\n";//insertar salto de línea
                            }
                            else
                            {
                                aux += "&nbsp;";//separar por espacio
                            }
                        }
                    }
                    objSP.Texto = aux;

                    foreach (IRfcStructure PO_ITEM in PO_ITEMS)
                    {
                        if (PO_ITEM["PO_NUMBER"].GetString().Equals(objSP.PO))
                        {
                            //objPO.NomSolicitante = PO_ITEM["DDTEXT"].GetString(); // Nombre SOlicitante
                            itm = new POItemBE();
                            itm.PO = objSP.PO;
                            itm.Pos = PO_ITEM["PO_ITEM"].GetString();
                            itm.Cod = PO_ITEM["MATERIAL"].GetString();
                            itm.Desc = PO_ITEM["SHORT_TEXT"].GetString();
                            itm.UM = PO_ITEM["UNIT"].GetString();
                            itm.ActFijo = PO_ITEM["ANLN1"].GetString();
                            itm.Precio = PO_ITEM["NET_PRICE"].GetDecimal();
                            itm.Cant = PO_ITEM["DISP_QUAN"].GetDecimal();
                            itm.CodProveedor = PO_ITEM["VENDOR"].GetString();
                            itm.DesProveedor = PO_ITEM["VEND_NAME"].GetString();
                            itm.Solicitante = PO_ITEM["PREQ_NAME"].GetString();
                            itm.TipoImputacion = PO_ITEM["ACCTASSCAT"].GetString();
                            itm.MotivoBloqueoPos = PO_ITEM["DDTEXT"].GetString();
                            itm.CodigoLiberacion = PO_ITEM["FRGCO"].GetString();
                            itm.CentCO = PO_ITEM["KOSTL"].GetString();
                            itm.NombRespCO = PO_ITEM["VERAK"].GetString();
                            itm.NroOrd = PO_ITEM["AUFNR"].GetString();
                            itm.DescCentCO = PO_ITEM["KTEXT"].GetString();
                            itm.DescNroOrd = PO_ITEM["KTEXT2"].GetString();
                            ////itm.Total = PO_ITEM["NET_PRICE"].GetDecimal();
                            itm.Moneda = objSP.Moneda;
                            objSP.Items.Add(itm);

                            foreach (IRfcStructure PO_CONTACT in PO_CONTACTS)
                            {
                                if (PO_CONTACT["LIFNR"].GetString().Equals(itm.CodProveedor))
                                {
                                    con = new POContactoBE();
                                    con.LIFNR = PO_CONTACT["LIFNR"].GetString();
                                    con.NAME_TEXT = PO_CONTACT["NAME_TEXT"].GetString();
                                    con.TEL_NUMBER = PO_CONTACT["TEL_NUMBER"].GetString();
                                    con.TEL_EXTENS = PO_CONTACT["TEL_EXTENS"].GetString();
                                    con.MOB_NUMBER = PO_CONTACT["MOB_NUMBER"].GetString();
                                    con.SMTP_ADDR = PO_CONTACT["SMTP_ADDR"].GetString();
                                    con.DEPARTMENT = PO_CONTACT["DEPARTMENT"].GetString();
                                    con.FUNCTION = PO_CONTACT["FUNCTION"].GetString();
                                    con.BNAME = PO_CONTACT["BNAME"].GetString();
                                    con.STREET = PO_CONTACT["STREET"].GetString();
                                    con.POST_CODE1 = PO_CONTACT["POST_CODE1"].GetString();
                                    con.CITY1 = PO_CONTACT["CITY1"].GetString();
                                    objSP.Contactos.Add(con);
                                }
                            }
                        }
                    }

                    foreach (IRfcStructure PO_REQUESTOR in PO_REQUESTORS)
                    {
                        if (PO_REQUESTOR["BNAME"].GetString().Equals(objSP.CodUsuario))
                        {
                            sol = new POSolicitanteBE();
                            sol.LIFNR = PO_REQUESTOR["LIFNR"].GetString();
                            sol.NAME_TEXT = PO_REQUESTOR["NAME_TEXT"].GetString();
                            sol.TEL_NUMBER = PO_REQUESTOR["TEL_NUMBER"].GetString();
                            sol.TEL_EXTENS = PO_REQUESTOR["TEL_EXTENS"].GetString();
                            sol.MOB_NUMBER = PO_REQUESTOR["MOB_NUMBER"].GetString();
                            sol.SMTP_ADDR = PO_REQUESTOR["SMTP_ADDR"].GetString();
                            sol.DEPARTMENT = PO_REQUESTOR["DEPARTMENT"].GetString();
                            sol.FUNCTION = PO_REQUESTOR["FUNCTION"].GetString();
                            sol.BNAME = PO_REQUESTOR["BNAME"].GetString();
                            sol.STREET = PO_REQUESTOR["STREET"].GetString();
                            sol.POST_CODE1 = PO_REQUESTOR["POST_CODE1"].GetString();
                            sol.CITY1 = PO_REQUESTOR["CITY1"].GetString();
                            objSP.Solicitantes.Add(sol);
                        }
                    }

                    lstSP.Add(objSP);
                }
            }
            catch (RfcBaseException e)
            {
                // Grabar Log de errores con e.message
                retVal = e.Message;
            }
            finally
            {

            }
            return retVal;
        }

        public string releaseSPFromHeader(List<POItemBE> lstSP, out List<ResultReleaseFromHeader> pLiberados)
        {
            string retval = string.Empty; IRfcFunction function = null; string retvaltmp = string.Empty;
            DestConfig dc = new DestConfig();
            RfcDestination dest = null;
            List<ResultReleaseFromHeader> pLibs = null;
            try
            {
                dest = DALC.getDestination(); //@@@
                //**********************************************************************************
                //USARLO CUANDO SE ENVIE A SAP UNA TABLA Z
                //**********************************************************************************
                ////creamos la tabla que será enviada a la funcion SAP
                //RfcStructureMetadata sm = dest.Repository.GetStructureMetadata("ZSMM_POITEM");
                //IRfcTable POITEMTable = sm.CreateTable();
                //IRfcStructure POITEM = sm.CreateStructure();

                //foreach (POItemBE item in lstSP)
                //{
                //    POITEM = sm.CreateStructure();
                //    POITEM.SetValue("PO_NUMBER", item.PO);
                //    POITEM.SetValue("PO_ITEM", item.Pos);
                //    POITEM.SetValue("FRGCO", item.CodigoLiberacion);
                //    POITEMTable.Append(POITEM);
                //}
                //**********************************************************************************
                foreach (POItemBE item in lstSP)
                {
                    function = dest.Repository.CreateFunction("BAPI_REQUISITION_RELEASE");
                    function.SetValue("NUMBER", item.PO);
                    function.SetValue("REL_CODE", item.CodigoLiberacion);
                    function.SetValue("ITEM", item.Pos);
                    function.SetValue("USE_EXCEPTIONS", string.Empty);
                    //function.SetValue("NO_COMMIT_WORK", "X");
                    function.Invoke(dest);
                    //lista donde se mostraran los mensajes, si en caso lo hubiera
                    pLibs = new List<ResultReleaseFromHeader>();
                    ResultReleaseFromHeader objLiberados = new ResultReleaseFromHeader();
                    retvaltmp = "";
                    IRfcTable RETURN = function.GetTable("RETURN");
                    foreach (IRfcStructure itm in RETURN)
                    {
                        retvaltmp += itm["MESSAGE"].GetString();
                    }

                    string strRelSta = function.GetString("REL_STATUS_NEW");
                    string strRelInd = function.GetString("REL_INDICATOR_NEW");
                    //int retCode = function.GetInt("RET_CODE");
                    objLiberados.pLiberado = string.IsNullOrEmpty(retvaltmp) ? true : false;
                    if (string.IsNullOrEmpty(retvaltmp))
                    {
                        //se hizo la liberación
                        retval += "Posición " + item.Pos + " liberado. ";
                    }
                    //else
                    //{
                    //    retval += "Posición " + item.Pos + " no liberado. ";
                    //}
                    objLiberados.CodSolicitud = item.PO;
                    objLiberados.Posicion = item.Pos;
                    objLiberados.Mensaje = retval;
                    objLiberados.DescripcionProducto = item.Desc;
                    pLibs.Add(objLiberados);
                }

            }
            catch (RfcCommunicationException e)
            {
                // network problem...
            }
            catch (RfcLogonException e)
            {
                // user could not logon...
            }
            catch (RfcAbapRuntimeException e)
            {
                // serious problem on ABAP system side...
            }
            catch (RfcAbapBaseException e)
            {
                // The function module returned an ABAP exception, an ABAP message
                // or an ABAP class-based exception...
            }
            catch (RfcBaseException e)
            {
                // Grabar Log de errores con e.message
                retval += e.Message;
            }
            finally
            {
                //RfcDestinationManager.UnregisterDestinationConfiguration(dc);
            }
            pLiberados = pLibs;
            return retval;
        }
    }
}
